package com.common.utils;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.sql.Time;
import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;

public class BeanUtils {
	public static final String TIMESTAMP_DATE_FORMAT ="yyyy-mm-dd hh:mm:ss.fffffffff";
	public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd HH:mm:ss SSS";
	public static final String DEFAULT_DATE_FORMAT2 = "yyyy-MM-dd HH:mm:ss";
	public static final String DATETIME_FORMAT = "yyyyMMddHHmmssSSS";
	public static final String DATE_FORMAT = "yyyy-MM-dd";

	public static final String DATE_TYPE_DAY = "DAY";
	public static final String DATE_TYPE_MONTH = "MONTH";
	public static final String DATE_TYPE_YEAR = "YEAR";
	public static final String DATE_TYPE_WEEK = "WEEK";
	public static final String DATE_TYPE_HOUR = "HOUR";
	public static final String DATE_TYPE_MINUTE = "MINUTE";
	public static final String DATE_TYPE_SECOND = "SECOND";
	public static final String PAGESIZEFLAG = "pageSizeFlag";
	public static final String STARTINDEXFLAG = "startIndexFlag";
	public static final int PAGESIZEFLAGVALUE = 10;
	public static final int STARTINDEXFLAGVALUE = 0;

	
	/**
	 *  stringToInt ���� 
	 * @param str
	 * @return
	 */
	public static int stringToInt(String flag, String str){
		int temp;
		if(flag.equals(PAGESIZEFLAG)){
			temp = PAGESIZEFLAGVALUE;
		}else if(flag.equals(STARTINDEXFLAG)){
			temp = STARTINDEXFLAGVALUE;
		}else{
			temp = -1;
		}
        if(str!=null&&!str.equals("")){
            try{
            	temp = new Integer(str.trim()).intValue();
            }catch(Exception e){ 
               System.out.println("--------Stringת��Ϊint����="+e);
            } 
         }
		return temp;
	}
	
	/**
	 * ���ַ���ת��ΪDate
	 * @param strDate String        ��ת����String���͵�����
	 * @param strDateFormat String  Date��ʽ
	 * @return Date                 ����Date���͵�����
	 */
	public static Date StringTodate(String strDate, String strDateFormat) {		
		if (strDate.length() <= 10) {
			strDate = strDate + " 00:00:00";
		}
		if (strDate == null || "".equals(strDateFormat) || strDateFormat == null) {
			strDateFormat = DEFAULT_DATE_FORMAT2;
		}
		Date rDate;
		SimpleDateFormat format = new SimpleDateFormat(strDateFormat);
		try {
			rDate = format.parse(strDate);
		}
		catch (Exception ex) {
			return null;
		}
		System.out.println("--------------------------rDate.toString()="+ rDate);
		return rDate;
	}

	/**
	 * ��stringת����ָ�����͵�Timestamp
	 * @param str String   ��ת����String���͵�����
	 * @param type String  ���ڸ�ʽ
	 * @return Timestamp   ����Timestamp���͵�����
	 */
	public static Timestamp cString2Timestamp(String str, String type) {
		if (type == null || type.equals("")) {
			type = DEFAULT_DATE_FORMAT2;
		}
		if (str.length() <= 10) {
			str = str + " 00:00:00";
		}
		SimpleDateFormat df = new SimpleDateFormat(type);
		try {
			return new Timestamp(df.parse(str).getTime());
		}
		catch (ParseException pe) {
			System.out.println(pe.getMessage());
			return null;
		}
	}

	/**
	 * ���һ��Class��������е�Field����,�����������Field����
	 * @param cls Class
	 * @throws NullPointerException
	 * @return String[]
	 */
	public static String[] getFields(Class cls) throws NullPointerException {
		String sStrs[] = null;
		sStrs = getDeclaredFields(cls);
		return sStrs;
	}

	/**
	 * ���һ��Class�����DeclaredField����
	 * @param cls Class
	 * @throws NullPointerException
	 * @return String[]
	 * @author dave
	 * @version 1.0
	 */
	public static String[] getDeclaredFields(Class cls) throws
	NullPointerException {
		if (cls == null) {
			throw new NullPointerException("����Class����Ϊnull!");
		}
		String strFields[] = null;
		Field fields[] = cls.getDeclaredFields();
		int length = fields.length;
		strFields = new String[length];

		for (int i = 0; i < length; i++) {
			strFields[i] = fields[i].getName();
		}
		return strFields;
	}

	/**
	 * �������������ͬ��Field Set��
	 * @param sourceBean Object
	 * @param targetBean Object
	 * @return Set
	 */
	public static Set getSameField(Object sourceBean, Object targetBean) {
		String str1s[], str2s[];
		str1s = getFields(sourceBean.getClass());
		str2s = getFields(targetBean.getClass());

		/**
		 * ��������������ͬ��field����
		 */
		Set fieldSet = new TreeSet();
		int str1sLength = str1s.length, str2sLength = str2s.length;
		for (int i = 0; i < str1sLength; i++) {
			for (int j = 0; j < str2sLength; j++) {
				if (str1s[i].equals(str2s[j])) {
					fieldSet.add(str1s[i]);
					break;
				}
			}
		}
		return fieldSet;
	}

	/**
	 * ���һ��Class�����DeclaredField����
	 * @param cls Class
	 * @throws NullPointerException
	 * @return Map
	 * @author dave
	 * @version 1.0
	 */
	public static Map getDeclaredFieldsAndFieldsType(Class cls) throws NullPointerException {
		if (cls == null) {
			throw new NullPointerException("����Class����Ϊnull!");
		}

		//JavaBean SET��GET����
		Method setMethod = null, getMethod = null;
		String strFields[] = null;
		Field fields[] = cls.getDeclaredFields();
		Method methods[] = cls.getDeclaredMethods();

		int length = fields.length;
		strFields = new String[length];
		Map fieldsAndFieldsTypeMap = new HashMap();
		Method method = null;
		Object fieldType = null;

		for (int i = 0; i < length; i++) {
			strFields[i] = fields[i].getName();
			//map�� (field���ƣ�field����)��ʽ���
			fieldsAndFieldsTypeMap.put(fields[i].getName(), fields[i].getType());
			System.out.println("--------"+fields[i].getName()+"-------"+fields[i].getType());
		}
		return fieldsAndFieldsTypeMap;
	}

	/**
	 * �����ݿ��е��ֶ�ӳ���javabean��get������
	 * �÷�����ҪΪBeanToBean������ΪJavaBean Object��Field�Ĵ�Сд�ǲ����ֵ�
	 * @param fieldName String       ���ݿ���ֶ���
	 * @return String                JavaBean��get������
	 */
	public static String getBeanGetMethodNameNoLowerCase(String fieldName) {
		StringBuffer sb = new StringBuffer();
		sb.append("get").append(getBeanMethodNameNoLowerCase(fieldName.trim()));
		return sb.toString();
	}

	/**
	 * �����ݿ��е��ֶ�ӳ���javabean��set������
	 * @param fieldName String       ���ݿ���ֶ���
	 * @return String                JavaBean��set������
	 */
	public static String getBeanSetMethodName(String fieldName) {
		StringBuffer sb = new StringBuffer();
		sb.append("set").append(getBeanMethodName(fieldName));
		return sb.toString();
	}

	/**
	 * �����ݿ��е��ֶ�ӳ���javabean���������ơ�
	 * @param fieldName String            ���ݿ���ֶ���
	 * @return String                     JavaBean�ĳ�Ա������
	 */
	public static String getBeanMethodName(String fieldName) {
		String firstLetter = fieldName.substring(0, 1);
		firstLetter = firstLetter.toUpperCase();
		String otherLeter = fieldName.substring(1, fieldName.length());
		/**
		 * ���뽫��ת��ΪСд
		 * ��Ϊͨ�� ResultSetMetaData ��õ��ֶ����ƴ�Сд����
		 * Ϊͳһά�������뽫���е�VO��Field��ΪСд
		 */
		otherLeter = otherLeter.toLowerCase();
		StringBuffer sb = new StringBuffer();
		sb.append(firstLetter).append(otherLeter);
		return sb.toString();
	}

	/**
	 * �����ݿ��е��ֶ�ӳ���javabean���������ơ�
	 * �÷�����ҪΪBeanToBean������ΪJavaBean Object��Field�Ĵ�Сд�ǲ����ֵ�
	 * @param fieldName String            ���ݿ���ֶ���
	 * @return String                     JavaBean�ĳ�Ա������
	 */
	public static String getBeanMethodNameNoLowerCase(String fieldName) {
		String firstLetter = fieldName.substring(0, 1);
		firstLetter = firstLetter.toUpperCase();
		String otherLeter = fieldName.substring(1, fieldName.length());
		StringBuffer sb = new StringBuffer();
		sb.append(firstLetter).append(otherLeter);
		return sb.toString();
	}

	/**
	 * ���ݷ������һ�������ֵ
	 * @param valueBean Object    �������
	 * @param parms  Object[]     ��������
	 * @return Object             ���ֵ
	 */
	public static Object getBeanMethodValue(Object valueBean, Method method,
			Object[] parms) throws Exception {
		Object rObject = null;
		try {
			rObject = method.invoke(valueBean, parms);
		}
		catch (Exception ex) {
			System.out.println(ex);
		}
		return rObject;
	}

	/**
	 * ����bean֮���໥ת��
	 * @param sourceBean Object          ��ת����ԴJavaBean����
	 * @param targetBean Object          ��ת����Ŀ��JavaBean��������
	 * @throws BeanUtilTransException    ת���쳣
	 * @return Object                    ����Ŀ��JavaBean����
	 */
	public static Object beanToBean(Object sourceBean, Object targetBean) throws
	Exception {
		if (sourceBean == null || targetBean == null) {
			throw new	Exception("VO����Ϊnull!");
		}
		try {
			System.out.println("-----------start--------");
			//JavaBean SET��GET����
			Method setMethod = null, getMethod = null;
			Field getField = null, setField = null;
			Object value = null;
			Class sFieldType = null;
			//����Filed����
			String sFieldName = null;
			String getMethodName = null, setMethodName = null;
			/**
			 * ��������������ͬ��field����
			 */
			Set fieldSet = new TreeSet();
			fieldSet = getSameField(sourceBean, targetBean);

			/**
			 * Դbean��Ŀ��beanת��
			 */
			for (Iterator it = fieldSet.iterator(); it.hasNext(); ) {

				sFieldName = (String) it.next();
				getField = sourceBean.getClass().getDeclaredField(sFieldName);
				setField = targetBean.getClass().getDeclaredField(sFieldName);				
				getMethodName = "get"+sFieldName.substring(0, 1).toUpperCase()+sFieldName.substring(1);
				setMethodName = "set"+sFieldName.substring(0, 1).toUpperCase()+sFieldName.substring(1);

				//���ת��ǰ��������Ե�ֵ
				getMethod = sourceBean.getClass().getDeclaredMethod( getMethodName, new Class[]{ });
				value=getMethod.invoke(sourceBean,new Object[]{});
				System.out.println("----------->>>>>>>>start  value="+value+"<<<<<<<<<---------");

				//���sourceBean������ֵ��Ϊnull���߲�Ϊ�գ�����targetBean����ͬ�����Ե�ֵ
				if(value!=null&&!value.equals("")){
					//��ȡtargetBean�����Ե�����
					sFieldType = targetBean.getClass().getDeclaredField(sFieldName).getType();
					//��ȡĿ��bean����
					setMethod = targetBean.getClass().getDeclaredMethod( setMethodName, new Class[]{  sFieldType });

					if(sFieldType.toString().equals("class java.math.BigDecimal")){
						BigDecimal[] instValue = new BigDecimal[1];
						instValue[0] = new BigDecimal(value.toString());					
						//ͨ��������Ŀ��bean��������ֵ�趨
						setMethod.invoke(targetBean, instValue);
						System.out.println("----------->>>>>>>>java.math.BigDecimal-------- value="+instValue[0]+"---------");

					}else if(sFieldType.toString().equals("class java.lang.String")){
						String[] instValue = new String[1];
						instValue[0] = value.toString();
						//ͨ��������Ŀ��bean��������ֵ�趨
						setMethod.invoke(targetBean, instValue);
						System.out.println("----------->>>>>>>>class java.lang.String-------- value="+instValue[0]+"---------");
					}else if(sFieldType.toString().equals("class java.util.Date")){
						Date[] instValue = new Date[1];
						instValue[0] = StringTodate(value.toString(), null);
						//ͨ��������Ŀ��bean��������ֵ�趨					
						setMethod.invoke(targetBean, instValue);
						System.out.println("----------->>>>>>>>class java.util.Date-------- value="+instValue[0]+"---------"+value+"-------"+value.toString());
					}else if(sFieldType.toString().equals("class java.sql.Time")){
						Time[] instValue = new Time[1];
						instValue[0] = (Time) value;
						//ͨ��������Ŀ��bean��������ֵ�趨
						setMethod.invoke(targetBean, instValue);
						System.out.println("----------->>>>>>>>class java.sql.Time-------- value="+instValue[0]+"---------");
					}else if(sFieldType.toString().equals("class java.sql.Timestamp")){
						Timestamp[] instValue = new Timestamp[1];
						instValue[0] = cString2Timestamp(value.toString(), null);
						//ͨ��������Ŀ��bean��������ֵ�趨
						setMethod.invoke(targetBean, instValue);
						System.out.println("----------->>>>>>>>class java.sql.Timestamp-------- value="+instValue[0]+"---------");
					}else if(sFieldType.toString().equals("class java.sql.Date")){
						java.sql.Date[] instValue = new java.sql.Date[1];
						instValue[0] = (java.sql.Date) value;
						//ͨ��������Ŀ��bean��������ֵ�趨
						setMethod.invoke(targetBean, instValue);
						System.out.println("----------->>>>>>>>class java.sql.Date-------- value="+instValue[0]+"---------");
					}else if(sFieldType.toString().equals("int")){
						Integer[] instValue = new Integer[1];
						instValue[0] = new Integer(value.toString());
						//ͨ��������Ŀ��bean��������ֵ�趨
						setMethod.invoke(targetBean, instValue);
						System.out.println("----------->>>>>>>>int-------- value="+instValue[0]+"---------");
					}else if(sFieldType.toString().equals("long")){
						Long[] instValue = new Long[1];
						instValue[0] = new Long(value.toString());
						//ͨ��������Ŀ��bean��������ֵ�趨
						setMethod.invoke(targetBean, instValue);
						System.out.println("----------->>>>>>>>long-------- value="+instValue[0]+"---------");
					}else if(sFieldType.toString().equals("float")){
						Float[] instValue = new Float[1];
						instValue[0] = new Float(value.toString());
						//ͨ��������Ŀ��bean��������ֵ�趨
						setMethod.invoke(targetBean, instValue);
						System.out.println("----------->>>>>>>>float-------- value="+instValue[0]+"---------");
					}else if(sFieldType.toString().equals("short")){
						Short[] instValue = new Short[1];
						instValue[0] = new Short(value.toString());
						//ͨ��������Ŀ��bean��������ֵ�趨
						setMethod.invoke(targetBean, instValue);
						System.out.println("----------->>>>>>>>short-------- value="+instValue[0]+"---------");
					}else if(sFieldType.toString().equals("double")){
						Double[] instValue = new Double[1];
						instValue[0] = new Double(value.toString());
						//ͨ��������Ŀ��bean��������ֵ�趨
						setMethod.invoke(targetBean, instValue);
						System.out.println("----------->>>>>>>>double-------- value="+instValue[0]+"---------");
					}else{

						System.out.println("----------->>>>>>>>String--------");
					}
				}

			}
			System.out.println("-----------end--------");
		}
		catch (Exception e) {
			System.out.println("-----------BeanToBeanת������"+e);
			//throw new Exception(e);		
		}
		return targetBean;
	}

	public static void main(String[] args) {

//		Vo1 v1= new Vo1();
//		java.math.BigDecimal big = new java.math.BigDecimal(100);
//
//		v1.setFiled6("100");
//		v1.setFiled1("1");
//		v1.setFiled2("sssssss2");
//		v1.setFiled3("343");
//		v1.setFiled4("232.3422");
//		v1.setFiled5("79.7988");
//		v1.setFiled7("sdsfsdfsafa");
//		v1.setFiled8("798");
//		v1.setFiled9("2008-01-01");
//		//v1.setFiled10("1970-01-01");
//		v1.setFiled11("ssssssssssss");
//		v1.setFiled12("1970-01-01");
//		//v1.setFiled13("1970-01-01");
//		
//		Vo2 v2= new Vo2();
//		//BeanUtils.getDeclaredFieldsAndFieldsType(v1.getClass());
//		try {
//			Object obj = BeanUtils.beanToBean(v1, v2);
//			v2 = (Vo2)obj;
//			
//		} catch (Exception e) {
//			e.printStackTrace();
//		}
//		
//		System.out.println("--------------------------getFiled1="+v2.getFiled1());
//		System.out.println("--------------------------getFiled2="+v2.getFiled2());
//		System.out.println("--------------------------getFiled3="+v2.getFiled3());
//		System.out.println("--------------------------getFiled4="+v2.getFiled4());
//		System.out.println("--------------------------getFiled5="+v2.getFiled5());
//		
//		System.out.println("--------------------------getFiled6="+v2.getFiled6());
//		System.out.println("--------------------------getFiled7="+v2.getFiled7());
//		System.out.println("--------------------------getFiled8="+v2.getFiled8());
//		System.out.println("--------------------------getFiled9="+v2.getFiled9());
//		System.out.println("--------------------------getFiled10="+v2.getFiled10());
//		
//		System.out.println("--------------------------getFiled11="+v2.getFiled11());
//		System.out.println("--------------------------getFiled12="+v2.getFiled12());
//		System.out.println("--------------------------getFiled13="+v2.getFiled13());
//
//		
//		System.out.println("--------------------------StringTodate="+BeanUtils.StringTodate("2005-01-10",null));
//		System.out.println("--------------------------StringTodate="+BeanUtils.StringTodate("2005-01-10 01:01:01",null));
//
//		//short sss = new short(11);
		
		
		System.out.println("------------sfsfs--------------"+BeanUtils.StringTodate("2008-2-2 00:00:00", null));
	}

}
